home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / hdf / unix / hdf3_2r2.lha / HDF3.2r2 / src / hkit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-28  |  20.7 KB  |  749 lines

  1. /***************************************************************************
  2. *
  3. *
  4. *                         NCSA HDF version 3.2r2
  5. *                            October 30, 1992
  6. *
  7. * NCSA HDF Version 3.2 source code and documentation are in the public
  8. * domain.  Specifically, we give to the public domain all rights for future
  9. * licensing of the source code, all resale rights, and all publishing rights.
  10. *
  11. * We ask, but do not require, that the following message be included in all
  12. * derived works:
  13. *
  14. * Portions developed at the National Center for Supercomputing Applications at
  15. * the University of Illinois at Urbana-Champaign, in collaboration with the
  16. * Information Technology Institute of Singapore.
  17. *
  18. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  19. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  20. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  21. *
  22. ****************************************************************************
  23. */
  24.  
  25. #ifdef RCSID
  26. static char RcsId[] = "@(#)$Revision: 1.5 $";
  27. #endif
  28. /*
  29. $Header: /hdf/hdf/v3.2r2/src/RCS/hkit.c,v 1.5 1992/10/23 00:14:11 koziol beta koziol $
  30.  
  31. $Log: hkit.c,v $
  32.  * Revision 1.5  1992/10/23  00:14:11  koziol
  33.  * Changed all DFIstr*() and DFImem*() calls to HDstr*() and HDmem*() calls
  34.  * #ifdef'd out the macros Jason defined for Hopen, Hclose, etc. for Vsets
  35.  * Replaced Vset VFREESPACE and VGETSPACE calls with actual calls to HDfreespace
  36.  * and HDgetspace
  37.  * Added a MS-Windows lower lower for file I/O (which may not be completely working
  38.  *
  39.  * Revision 1.3  1992/10/12  18:11:51  koziol
  40.  * Updated for v3.2r2 release
  41.  *
  42.  * Revision 1.2  1992/08/26  19:44:25  chouck
  43.  * Moved HDgettagname() into hkit.c and added calibration tag
  44.  *
  45.  * Revision 1.1  1992/08/25  21:40:44  koziol
  46.  * Initial revision
  47.  *
  48. */
  49. #include <ctype.h>
  50. #include "hdf.h"
  51. #include "herr.h"
  52. #include "hfile.h"
  53.  
  54. /*-----------------------------------------------------------------------------
  55.  * Name:    HIstrncpy
  56.  * Purpose: This function creates a string in dest that is at most
  57.  *          'len' characters long.  The 'len' characters *include* the
  58.  *          NULL terminatior which must be added for historical reasons.
  59.  *          So if you have the string "Foo\0" you must call this copy
  60.  *          function with len == 4
  61.  * Inputs:  dest, source: destination and source for copy
  62.  *          len: max length of the outgoing string
  63.  * Returns: Address of dest.
  64.  * Users:   HDF systems programmers
  65.  * Remarks:
  66.  *---------------------------------------------------------------------------*/
  67.  
  68. #if defined PROTOTYPE
  69. char *HIstrncpy(register char *dest,register char *source,int32 len)
  70. #else
  71. char *HIstrncpy(dest, source, len)
  72. register char *source, *dest;
  73. int32 len;
  74. #endif /* PROTOTYPE */
  75. {
  76.     char *destp;
  77.  
  78.     destp = dest;
  79.     if (len == 0) return(destp);
  80.     for(; (len > 1) && (*source != '\0');len--)
  81.         *dest++ = *source++;
  82.     *dest = '\0';       /* Force the last byte be '\0'   */
  83.     return(destp);
  84. }   /* end HIstrncpy() */
  85.  
  86. #ifdef PC
  87. #ifdef WIN3
  88. int32 HDspaceleft(void)
  89. {
  90. /* return the largest amount of memory Windows can give us */
  91.    return(GlobalCompact(0));
  92. }
  93. #else /* WIN3 */
  94. int32 HDspaceleft(void)
  95. {
  96.     struct _heapinfo h_info;        /* structure for heap information, defined in <malloc.h> */
  97.     int heap_status;                /* the current condition of the heap */
  98.     int32 total_free,total_used;    /* variables to store the amount used and the amount free in the heap */
  99.  
  100.     total_free=0;
  101.     total_used=0;
  102.     h_info._pentry=NULL;
  103.     for(;;) {
  104.         heap_status=_heapwalk(&h_info);
  105.         if(heap_status!=_HEAPOK)
  106.             break;
  107.         if(h_info._useflag==_USEDENTRY)
  108.             total_used+=h_info._size;
  109.         else
  110.             total_free+=h_info._size;
  111.     } /* end for */
  112.     switch(heap_status) {
  113.         case _HEAPEND:
  114.         case _HEAPEMPTY:
  115.             break;
  116.  
  117.         case _HEAPBADBEGIN:
  118.             printf("%s block at %Fp of size %4.4X\n",(h_info._useflag==_USEDENTRY ? "USED" : "FREE"),h_info._pentry,h_info._size);
  119.             printf("ERROR - heap is damaged\n\n");
  120.             return((int32)-1);
  121.  
  122.         case _HEAPBADPTR:
  123.             printf("%s block at %Fp of size %4.4X\n",(h_info._useflag==_USEDENTRY ? "USED" : "FREE"),h_info._pentry,h_info._size);
  124.             printf("ERROR - bad pointer to heap\n\n");
  125.             return((int32)-1);
  126.  
  127.         case _HEAPBADNODE:
  128.             printf("%s block at %Fp of size %4.4X\n",(h_info._useflag==_USEDENTRY ? "USED" : "FREE"),h_info._pentry,h_info._size);
  129.             printf("ERROR - bad node in heap\n\n");
  130.             return((int32)-1);
  131.     } /* end switch */
  132.     return((int32)total_free);
  133. } /* end HDspaceleft() */
  134. #endif /* WIN3 */
  135. #endif /* PC */
  136.  
  137.  
  138. #ifdef PC
  139. #ifdef WIN3
  140. void *HDgetspace(uint32 qty)
  141. {
  142.     char *FUNC="HDgetspace";
  143.  
  144.     HANDLE mem_handle;  /* handle of the memory allocated */
  145.     HANDLE *handle_addr;/* pointer to the HANDLE stored in the memory block */
  146.     char huge *p1;
  147.     char *p2;
  148.  
  149.     if (qty <= (uint32)128) {
  150.         mem_handle=LocalAlloc(LMEM_MOVEABLE, (WORD)qty+sizeof(HANDLE)+1);
  151.         if (mem_handle==NULL) {
  152.             HERROR(DFE_NOSPACE);
  153.             return(NULL);
  154.         }
  155.         handle_addr=(HANDLE *)(p2=(char *)LocalLock(mem_handle));
  156.         if (handle_addr==NULL) {
  157.             HERROR(DFE_NOSPACE);
  158.             return(NULL);
  159.         }
  160.         *handle_addr=mem_handle;
  161.         *((char *)handle_addr+sizeof(HANDLE))=0;
  162.         return (p2+sizeof(HANDLE)+1);
  163.     } else {
  164.         mem_handle=GlobalAlloc(GMEM_MOVEABLE,(DWORD)(qty+sizeof(HANDLE)+1));
  165.         if(mem_handle==NULL) {
  166.             HERROR(DFE_NOSPACE);
  167.             return(NULL);
  168.         }
  169.         /* lock down the block, use GlobalWire because we don't know how long */
  170.         /*  this potentially large block will be used */
  171.         handle_addr=(HANDLE *)(p1=(char huge *)GlobalWire(mem_handle));
  172.         if (handle_addr==NULL) {
  173.             HERROR(DFE_NOSPACE);
  174.             return(NULL);
  175.         }
  176.         *handle_addr=mem_handle;    /* store the handle in the first part of the memory block */
  177.         *((char *)handle_addr+sizeof(HANDLE))=1;
  178.         return(p1+sizeof(HANDLE)+1);
  179.     }
  180. }
  181.  
  182. void *HDfreespace(void *ptr)
  183. {
  184.     HANDLE mem_handle;  /* handle of the memory allocated */
  185.     HANDLE *handle_addr;/* pointer to the HANDLE stored in the memory block */
  186.  
  187.     if(ptr!=NULL) {
  188. /* get the address of the handle, which is stored in the memory block itself */
  189.         handle_addr=(HANDLE *)((char *)ptr-sizeof(HANDLE)-1);
  190.         mem_handle=*handle_addr;    /* get the handle from the memory block */
  191.         if (*((char *)ptr-1)) {
  192.             GlobalUnWire(mem_handle);     /* unlock the block */
  193.             GlobalFree(mem_handle);       /* free the block */
  194.         } else {
  195.             LocalUnlock(mem_handle);
  196.             LocalFree(mem_handle);
  197.         }
  198.     } /* end if */
  199.     return(NULL);
  200. }
  201. #else /* !WIN3 */
  202. void *HDgetspace(uint32 qty)
  203. {
  204.     char *FUNC="HDgetspace";
  205.     char huge *p;
  206.     char *p2;
  207.  
  208.     qty++;    /* increment the quantity to allocate to allow for the extra byte we are going to include */
  209.  
  210.     if(qty>=(int32)64000) {   /* see if we have to use halloc() to get a really large chunk of memory */
  211.         p = halloc((int32)qty,(size_t)1);
  212.         if (p==NULL) {
  213.             HERROR(DFE_NOSPACE);
  214.             return(NULL);
  215.           } /* end if */
  216.         *p=1;           /* indicate that halloc() was used to acquire this memory */
  217.         p++;
  218.         return((char huge *)p);
  219.       } /* end if */
  220.     else {      /* we can get away with just malloc() */
  221.         p2 = malloc((size_t)qty);
  222.         if (p2==NULL) {
  223.             HERROR(DFE_NOSPACE);
  224.             return(NULL);
  225.           } /* end if */
  226.         *p2=0;           /* indicate that malloc() was used to acquire this memory */
  227.         p2++;
  228.         return((char huge *)p2);
  229.       } /* end else */
  230. }
  231.  
  232. void *HDfreespace(void *ptr)
  233. {
  234.     if(ptr==NULL)
  235.         return(NULL);
  236.  
  237.     ptr = (char *)ptr-1;      /* decrement the pointer to free */
  238.     if(*(char *)ptr)   /* check whether block of memory was allocated with halloc() */
  239.         hfree(ptr);
  240.     else       /* memory was allocated through malloc() */
  241.         free(ptr);
  242.     return(NULL);
  243. }
  244. #endif /* WIN3 */
  245. #else /* PC */
  246.  
  247.  
  248. #if defined PROTOTYPE
  249. void *HDgetspace(uint32 qty)
  250. #else
  251. void *HDgetspace(qty)
  252. uint32 qty;
  253. #endif /* PROTOTYPE */
  254. {
  255.     char *FUNC="HDgetspace";
  256.     char *p;
  257.  
  258.     p = (char *) malloc(qty);
  259.     if (p== (char *) NULL) {
  260.         HERROR(DFE_NOSPACE);
  261.         HEreport("Attempted to allocate %d bytes", qty);
  262.         return(NULL);
  263.     }
  264.     return(p);
  265. }
  266.  
  267. #if defined PROTOTYPE
  268. void *HDfreespace(void *ptr)
  269. #else
  270. void *HDfreespace(ptr)
  271. void *ptr;
  272. #endif /* PROTOTYPE */
  273. {
  274.     if (ptr!=NULL) free(ptr);
  275.     return(NULL);
  276. }
  277.  
  278. #endif /* PC */
  279.  
  280. #if defined PROTOTYPE 
  281. intn HDc2fstr(char *str, int len)
  282. #else
  283. intn HDc2fstr(str, len)
  284. char* str;
  285. int len;
  286. #endif /* PROTOTYPE */
  287. {
  288.     int i;
  289.  
  290.     for(i=0; (str[i]); i++)
  291.         /* EMPTY */;
  292.     for(; i<len; i++) str[i] = ' ';
  293.     return 0;
  294. }
  295.  
  296. #if defined PROTOTYPE
  297. char *HDf2cstring(_fcd fdesc, intn len)
  298. #else
  299. char *HDf2cstring(fdesc, len)
  300.     _fcd fdesc;
  301.     intn len;
  302. #endif /* PROTOTYPE */
  303. {
  304.     char *cstr, *str;
  305.     int i;
  306.  
  307.     str = _fcdtocp(fdesc);
  308.     for(i=len-1;i>=0 && (!isascii(str[i]) || !isgraph(str[i])); i--)
  309.         /*EMPTY*/;
  310.     cstr = (char *)HDgetspace(i+2);
  311.     cstr[i+1] = '\0';
  312.     for (; i>=0; i--) cstr[i] = str[i];
  313.     return cstr;
  314. }
  315.  
  316. /*--------------------------------------------------------------------------
  317.  HIlookup_dd
  318.  
  319.  find the dd with tag and ref, by returning the block where the dd resides
  320.  and the index of the dd in the ddblock ddlist.
  321.  
  322.  This function is different from HIfind_dd in that it does not understand
  323.  any ordering in the file.  Wildcards sent to this routine (i.e. to
  324.  get the 'next' widget get passed off to HIfind_dd().
  325.  
  326.  Return FAIL or SUCCEED
  327. --------------------------------------------------------------------------*/
  328. #ifdef PROTOTYPE
  329. int HIlookup_dd(filerec_t *file_rec, uint16 look_tag, uint16 look_ref, 
  330.                 ddblock_t **pblock, int32 *pidx)
  331. #else
  332. int HIlookup_dd(file_rec, look_tag, look_ref, pblock, pidx)
  333.      filerec_t *file_rec;       /* the file */
  334.      uint16 look_tag;           /* tag of dd to look for */
  335.      uint16 look_ref;           /* ref of dd to look for */
  336.      ddblock_t **pblock;        /* OUT: ddblock where dd is found */
  337.      int32 *pidx;               /* OUT: index into ddlist where dd is found */
  338. #endif
  339.   char *FUNC="HIlookup_dd";       /* for HERROR */
  340.   register intn tag, ref, key;
  341.   register tag_ref_list_ptr p;
  342.  
  343.   if(look_tag == DFTAG_WILDCARD || look_ref == DFREF_WILDCARD)
  344.     return (HIfind_dd(look_tag, look_ref, pblock, pidx));
  345.  
  346.   tag = (intn) look_tag;
  347.   ref = (intn) look_ref;
  348.  
  349.   /*
  350.    * Look for the normal version 
  351.    */
  352.   key = tag + ref;
  353.  
  354.   for(p = file_rec->hash[key & HASH_MASK]; p; p = p->next) {
  355.     if(p->tag == tag && p->ref == ref) {
  356.       *pblock = p->pblock;
  357.       *pidx   = p->pidx;
  358.       return SUCCEED;
  359.     }
  360.   }
  361.  
  362.   /*
  363.    * Try looking for the special version of this tag
  364.    */
  365.   tag = (intn) MKSPECIALTAG(look_tag);
  366.   key = tag + ref;
  367.  
  368.   for(p = file_rec->hash[key & HASH_MASK]; p; p = p->next) {
  369.     if(p->tag == tag && p->ref == ref) {
  370.       *pblock = p->pblock;
  371.       *pidx   = p->pidx;
  372.       return SUCCEED;
  373.     }
  374.   }
  375.  
  376.   return FAIL;
  377.  
  378. } /* HIlookup_dd */
  379.  
  380. /* ---------------------------- HIadd_hash_dd ----------------------------- */
  381. /*
  382.   Add a new dd into the hash table
  383.  
  384.   Return SUCCEED or FAIL
  385. */
  386. #ifdef PROTOTYPE
  387. int HIadd_hash_dd(filerec_t *file_rec, uint16 look_tag, uint16 look_ref, 
  388.                 ddblock_t *pblock, int32 pidx)
  389. #else
  390. int HIadd_hash_dd(file_rec, look_tag, look_ref, pblock, pidx)
  391.      filerec_t *file_rec;      /* the file */
  392.      uint16 look_tag;           /* tag of dd to add */
  393.      uint16 look_ref;           /* ref of dd to add */
  394.      ddblock_t *pblock;         /* ddblock where dd is  */
  395.      int32 pidx;                /* index into ddlist where dd is */
  396. #endif
  397. {
  398.   char *FUNC="HIadd_hash_dd";       /* for HERROR */
  399.   register intn tag, ref, key;
  400.   register tag_ref_list_ptr p;
  401.  
  402.   if(look_tag == DFTAG_NULL) return SUCCEED;
  403.  
  404.   tag = (intn) look_tag;
  405.   ref = (intn) look_ref;
  406.   key = tag + ref;
  407.  
  408.   if(!(p = (tag_ref_list_ptr) HDgetspace((uint32)sizeof(tag_ref_list))))
  409.     HRETURN_ERROR(DFE_NOSPACE, FAIL);
  410.   
  411.   p->pblock = pblock;
  412.   p->pidx   = pidx;
  413.   p->tag    = tag;
  414.   p->ref    = ref;
  415.   p->next   = file_rec->hash[key & HASH_MASK];        
  416.   file_rec->hash[key & HASH_MASK] = p;
  417.   
  418.   return SUCCEED;
  419.  
  420. } /* HIadd_hash_dd */
  421.  
  422.  
  423. /* ---------------------------- HIdel_hash_dd ----------------------------- */
  424. /*
  425.   Delete a dd from the hash table
  426.  
  427.   Return SUCCEED or FAIL
  428. */
  429. #ifdef PROTOTYPE
  430. int HIdel_hash_dd(filerec_t *file_rec, uint16 look_tag, uint16 look_ref)
  431. #else
  432. int HIdel_hash_dd(file_rec, look_tag, look_ref)
  433.      filerec_t *file_rec;      /* the file */
  434.      uint16 look_tag;           /* tag of dd to add */
  435.      uint16 look_ref;           /* ref of dd to add */
  436. #endif
  437. {
  438.   char *FUNC="HIdel_hash_dd";       /* for HERROR */
  439.   register intn tag, ref, key;
  440.   register tag_ref_list_ptr p, prev;
  441.  
  442.   tag = (intn) look_tag;
  443.   ref = (intn) look_ref;
  444.   key = tag + ref;
  445.   
  446.   p = file_rec->hash[key & HASH_MASK]; 
  447.  
  448.   if(!p) return SUCCEED;
  449.  
  450.   prev = NULL;
  451.   for(p = file_rec->hash[key & HASH_MASK]; p; p = p->next) {
  452.     if(p->tag == tag && p->ref == ref) {
  453.       if(prev)
  454.         prev->next = p->next;
  455.       else
  456.         file_rec->hash[key & HASH_MASK] = p->next;
  457.  
  458.       HDfreespace(p);
  459.       return SUCCEED;
  460.     }
  461.     prev = p;
  462.   }
  463.  
  464.   return SUCCEED;
  465.  
  466. } /* HIdel_hash_dd */
  467.  
  468.  
  469. /*--------------------------------------------------------------------------
  470.  HIfind_dd
  471.  
  472.  find the dd with tag and ref, by returning the block where the dd resides
  473.  and the index of the dd in the ddblock ddlist.
  474. --------------------------------------------------------------------------*/
  475. #ifdef PROTOTYPE
  476. int HIfind_dd(uint16 look_tag, uint16 look_ref, ddblock_t **pblock, int32 *pidx)
  477. #else
  478. int HIfind_dd(look_tag, look_ref, pblock, pidx)
  479.     uint16 look_tag;           /* tag of dd to look for */
  480.     uint16 look_ref;           /* ref of dd to look for */
  481.     ddblock_t **pblock;        /* IN: ddblock to start looking for the dd */
  482.                                /* OUT: ddblock where dd is found */
  483.     int32 *pidx;               /* IN: index before place in ddlist
  484.                                   to start searching */
  485.                                /* OUT: index into ddlist where dd is found */
  486. #endif
  487. {
  488.     register int32 idx;             /* index into ddlist of current dd searched */
  489.     register ddblock_t *block;      /* ptr to current ddblock searched */
  490.     register dd_t *list;            /* ptr to current ddlist searched */
  491.  
  492. #ifndef oldspecial
  493.     uint16 special_tag;                /* corresponding special tag */
  494.  
  495.     /* search for special version also */
  496.  
  497.     special_tag = MKSPECIALTAG(look_tag);
  498. #endif
  499.  
  500.     /* start searching on the next dd */
  501.     idx = *pidx + 1;
  502.     for (block = *pblock; block; block = block->next) {
  503.  
  504.        list = block->ddlist;
  505.        for (; idx < block->ndds; idx++) {
  506.  
  507.            /* skip the empty dd's */
  508.  
  509.            if (list[idx].tag == DFTAG_NULL && look_tag != DFTAG_NULL)
  510.                continue;
  511.  
  512.            if(((look_tag == DFTAG_WILDCARD || list[idx].tag == look_tag)
  513. #ifndef oldspecial
  514.                 || (special_tag != DFTAG_NULL && list[idx].tag == special_tag)
  515. #endif
  516.               ) && (look_ref == DFREF_WILDCARD || list[idx].ref == look_ref)) {
  517.  
  518.                /* we have a match !! */
  519.  
  520.                *pblock = block;
  521.                *pidx = idx;
  522.                return SUCCEED;
  523.            }
  524.        }
  525.  
  526.        /* start from beginning of the next dd list */
  527.  
  528.        idx = 0;
  529.     }
  530.  
  531.     /* nothing found */
  532.  
  533.     return FAIL;
  534. } /* HIfind_dd */
  535.  
  536. /* ------------------------------- HDflush -------------------------------- */
  537. /*
  538.  
  539.   Force the system to flush the HDF file stream
  540.  
  541.   This should be primarily used for debugging
  542.  
  543.   The MAC does not really support fflush() so this routine just returns
  544.     SUCCEED always on a MAC w/o really doing anything.
  545.  
  546. */
  547.  
  548. #ifdef PROTOTYPE
  549. intn HDflush(int32 file_id)
  550. #else
  551. intn HDflush(file_id)
  552.     int32 file_id;             /* id of file to flush */
  553. #endif
  554. {
  555.     char *FUNC="HDflush";       /* for HERROR */
  556.  
  557. #ifndef MAC
  558.  
  559.     filerec_t *file_rec;
  560.     
  561.     file_rec = FID2REC(file_id);
  562.     if (!file_rec || file_rec->refcount == 0) {
  563.         HERROR(DFE_ARGS);
  564.         return FAIL;
  565.     }
  566.     
  567.     fflush(file_rec->file);
  568.  
  569. #endif /* MAC */
  570.  
  571.     return SUCCEED;
  572.  
  573. } /* HDflush */
  574.  
  575.  
  576. /* ---------------------------- HDpackFstring ----------------------------- */
  577. /*
  578.  
  579.   HDpackFstring -- given a NULL terminated C string 'src' convert it to
  580.   a space padded Fortran string 'dest' of length 'len'
  581.  
  582. */
  583. intn
  584. #ifdef PROTOTYPE
  585. HDpackFstring(char *src, char *dest, intn len)
  586. #else
  587. HDpackFstring(src, dest, len)
  588. char *src, *dest;
  589. intn len;
  590. #endif
  591. {
  592.  
  593.     intn sofar;
  594.     
  595.     for(sofar = 0; (sofar < len) && (*src != '\0'); sofar++)
  596.         *dest++ = *src++;
  597.  
  598.     while(sofar++ < len)
  599.         *dest++ = ' ';
  600.  
  601.     return SUCCEED;
  602.  
  603. }
  604.  
  605.  
  606. /*--------------------------------------------------------------------------
  607.  *  HDgettagname(tag) : map a tag to its corresponding name
  608.  *                      return NULL if tag is unknown.
  609.  *
  610.  *  NOTE: Please keep tag names <= 30 characters - a 
  611.  *        lot of pretty-printing code depends on it.
  612. --------------------------------------------------------------------------*/
  613. #ifdef PROTOTYPE
  614. char *HDgettagname(uint16 tag)
  615. #else
  616. char *HDgettagname(tag)
  617.      uint16 tag;
  618. #endif /* PROTOTYPE */
  619. {
  620.  
  621.   char *name;
  622.  
  623.   switch(tag) {
  624.       
  625.       /* Utility Tags */
  626.   case DFTAG_NULL  :
  627.       name = "No Data"; break;
  628.   case DFTAG_VERSION :
  629.       name = "Version Descriptor"; break;
  630.   case DFTAG_LINKED :
  631.       name = "Linked Blocks Indicator"; break;
  632.   case DFTAG_FID   : 
  633.       name = "File Identifier"; break;
  634.   case DFTAG_FD    :   
  635.       name = "File Description"; break;
  636.   case DFTAG_TID   :
  637.       name = "Tag Identifier"; break;
  638.   case DFTAG_TD    : 
  639.       name = "Tag Description"; break;
  640.   case DFTAG_DIL   :
  641.       name = "Data Id Label"; break;
  642.   case DFTAG_DIA   :    
  643.       name = "Data Id Annotation"; break;
  644.   case DFTAG_NT    :    
  645.       name = "Number type"; break;
  646.   case DFTAG_MT    :   
  647.       name = "Machine type"; break;
  648.       
  649.       /* raster-8 Tags */
  650.   case DFTAG_ID8   :   
  651.       name = "Image Dimensions-8"; break;
  652.   case DFTAG_IP8   :   
  653.       name = "Image Palette-8"; break;
  654.   case DFTAG_RI8   :  
  655.       name = "Raster Image-8"; break;
  656.   case DFTAG_CI8   : 
  657.       name = "RLE Compressed Image-8"; break;
  658.   case DFTAG_II8   :  
  659.       name = "Imcomp Image-8"; break;
  660.       
  661.       /* Raster Image Tags */
  662.   case DFTAG_ID    :  
  663.       name = "Image Dimensions"; break;
  664.   case DFTAG_LUT   :  
  665.       name = "Image Palette"; break;
  666.   case DFTAG_RI    : 
  667.       name = "Raster Image Data"; break;
  668.   case DFTAG_CI    :  
  669.       name = "Compressed Image"; break;
  670.   case DFTAG_RIG   : 
  671.       name = "Raster Image Group"; break;
  672.   case DFTAG_LD    : 
  673.       name = "Palette Dimension"; break;
  674.   case DFTAG_MD    :
  675.       name = "Matte Dimension"; break;
  676.   case DFTAG_MA    :
  677.       name = "Matte Data"; break;
  678.   case DFTAG_CCN   :   
  679.       name = "Color Correction"; break;
  680.   case DFTAG_CFM   : 
  681.       name = "Color Format"; break;
  682.   case DFTAG_AR    :   
  683.       name = "Aspect Ratio"; break;
  684.   case DFTAG_DRAW  :
  685.       name = "Sequenced images"; break;
  686.   case DFTAG_RUN   :   
  687.       name = "Runable program / script"; break;
  688.   case DFTAG_XYP   : 
  689.       name = "X-Y position"; break;
  690.   case DFTAG_MTO   :  
  691.       name = "M/c-Type override"; break;
  692.       
  693.       /* Tektronix */
  694.   case DFTAG_T14   :   
  695.       name = "TEK 4014 Data"; break;
  696.   case DFTAG_T105  :
  697.       name = "TEK 4105 data"; break;
  698.       
  699.       /* Compression Schemes */
  700.   case DFTAG_RLE   : 
  701.       name = "Run Length Encoding"; break;
  702.   case DFTAG_IMCOMP : 
  703.       name = "IMCOMP Encoding"; break;
  704.       
  705.       /* Scientific / Numeric Data Sets */
  706.   case DFTAG_SDG   : 
  707.       name = "Scientific Data Group"; break;
  708.   case DFTAG_NDG   : 
  709.       name = "Numeric Data Group"; break;
  710.   case DFTAG_SD    :
  711.       name = "Scientific Data"; break;
  712.   case DFTAG_SDD   : 
  713.     name = "SciData description"; break;
  714.   case DFTAG_SDL   :   
  715.       name = "SciData labels"; break;
  716.   case DFTAG_SDU   : 
  717.       name = "SciData units"; break;
  718.   case DFTAG_SDF   :  
  719.       name = "SciData formats"; break;
  720.   case DFTAG_SDS   :  
  721.       name = "SciData scales"; break;
  722.   case DFTAG_SDM   :  
  723.       name = "SciData max/min"; break;
  724.   case DFTAG_SDC   :  
  725.       name = "SciData coordsys"; break;
  726.   case DFTAG_SDT   :  
  727.       name = "Transpose"; break;
  728.   case DFTAG_SDLNK :  
  729.       name = "Links related to the dataset"; break;
  730.   case DFTAG_CAL   :  
  731.       name = "Calibration information"; break;
  732.       
  733.       /* V Group Tags */
  734.   case DFTAG_VG   :  
  735.       name = "Vgroup"; break;
  736.   case DFTAG_VH   : 
  737.       name = "Vdata"; break;
  738.   case DFTAG_VS   : 
  739.       name = "Vdata Storage"; break;
  740.   default:
  741.       name = (char *) NULL;
  742.       break;
  743.   }
  744.   
  745.   return name;
  746.   
  747. }
  748.